#ifndef _FASTApi_h_
#define _FASTApi_h_ 1

#include "types.h"
#include "common.h"
#include <string>
#include <sstream>
#include <vector>

typedef enum eFAST_SIGN_MASK {
	SIGN_MASK_I32 = 0x40, SIGN_MASK_U32 = 0x00, SIGN_MASK_I64 = 0x40, SIGN_MASK_U64 = 0x00,
} eFAST_SIGN_MASK;

//#define SIGN_MASK_I32 0x40
//#define SIGN_MASK_U32 0x00
//#define SIGN_MASK_I64 0x40
//#define SIGN_MASK_U64 0x00

#define STR_ARGS(_x) _x, sizeof (_x)
#define STR_ARGS_LEN(_x) _x, sizeof (_x)

#define EMPTY 0
#define DONOT 1


#define int32Min -2147483648
#define int32Max 2147483647
#define uInt32Min 0
#define uInt32Max 4294967295
#define int64Min -9223372036854775808
#define int64Max 9223372036854775807
#define uInt64Min 0
#define uInt64Max 18446744073709551615

#define ERR_S1 "ERR S1: XML syntax are in fact not well-formed, do not follow the rules of XML namespaces or are invalid with respect to the schema"
#define ERR_S2 "ERR S2: The operator is specified for a field of a type to which the operator is not applicable"
#define ERR_S3 "ERR S3: The initial value specified by the value attribute in the concrete syntax cannot be converted to a value of the type of the field"
#define ERR_S4 "ERR S4: The initial value is specified for a constant operator"
#define ERR_S5 "ERR S5: The initial value is specified for a default operator on a mandatory field"

#define ERR_D1 "ERR D1: The type of a field in a template cannot be converted to or from the type of the corresponding application field"
#define ERR_D2 "ERR D2: The integer in the stream does not fall within the bounds of the specific integer type specified on the corresponding field"
#define ERR_D3 "ERR D3: The decimal value cannot be encoded due to limitations introduced by using individual operators on exponent and mantissa"
#define ERR_D4 "ERR D4: The type of the previous value is not the same as the type of the field of the current operator"
#define ERR_D5 "ERR D5: The mandatory field is not present in the stream, has an undefined previous value and there is no initial value in the instruction context"
#define ERR_D6 "ERR D6: The mandatory field is not present in the stream and has an empty previous value"
#define ERR_D7 "ERR D7: The subtraction length exceeds the length of the base value or if it does not fall in the value rang of an int32"
#define ERR_D8 "ERR D8: The name specified on a static template reference does not point to a template known by the encoder or decoder"
#define ERR_D9 "ERR D9: The decoder cannot find a template associated with a template identifier appearing in the stream"
#define ERR_D10 "ERR D10: Converting byte vectors to and from other types than strings"
#define ERR_D11 "ERR D11: The syntax of a string does not follow the rules for the type converted to"
#define ERR_D12 "ERR D12: The block length preamble is zero"

#define ERR_R1 "ERR R1: The decimal cannot be represented by an exponent in the range [-63 � 63] or if the mantissa does not fit in an int64"
#define ERR_R2 "ERR R2: The combined value after applying a tail or delta operator to a Unicode string is not a valid UTF-8 sequence"
#define ERR_R3 "ERR R3: The unicode string that is being converted to an ASCII string contains characters that are outside the ASCII character set"
#define ERR_R4 "ERR R4: The value of an integer type cannot be represented in the target integer type in a conversion"
#define ERR_R5 "ERR R5: The decimal being converted to an integer has a negative exponent or if the resulting integer does not fit the target integer type"
#define ERR_R6 "ERR R6: The integer appears in an overlong encoding"
#define ERR_R7 "ERR R7: The presence map is overlong"
#define ERR_R8 "ERR R8: The presence map contains more bits than required"
#define ERR_R9 "ERR R9: The string appears in an overlong encoding."


//////////////////////////////////////////////////////////////////////
#define STOP_BIT  0x80
#define VALUE_BIT  0x7F

typedef enum eFAST_TEMPLATE {
	eFAST_TID_TEMPLATE = 97, eFAST_HDR_TEMPLATE = 98, eFAST_TRL_TEMPLATE = 99,
} eFAST_TEMPLATE;

typedef enum eFAST_PMAP_BIT {
	ePMAP_BIT_OFF = 0x00, ePMAP_BIT_ON = 0x01,
} eFAST_PMAP_BIT;

typedef enum eFAST_OP {
	eFAST_OP_NONE = 0,
	eFAST_OP_DEFAULT,
	eFAST_OP_CONST,
	eFAST_OP_COPY,
	eFAST_OP_INCR,
	eFAST_OP_DELTA,
	eFAST_OP_TAIL,
} eFAST_OP;

typedef enum eFAST_TYPE {
	eFAST_TYPE_I32 = 0, /*Integer 32bit signed and unsigned*/
	eFAST_TYPE_U32, /*Integer 32bit unsigned*/
	eFAST_TYPE_I64, /*Integer 64bit signed and unsigned*/
	eFAST_TYPE_U64, /*Integer 64bit signed and unsigned*/
	eFAST_TYPE_ASCII, /*Ascii string*/
	eFAST_TYPE_DECMIAL, /*Decimal*/
	eFAST_TYPE_UNICODE, /*UNICODE string*/
	eFAST_TYPE_BYTEVECTOR, /*BYTE VECTOR*/
	eFAST_TYPE_GROUP, /*Group*/
	eFAST_TYPE_COMPONENT, /*Component Length + Repeating Group*, this is called sequence also*/
	eFAST_TYPE_NULL = 0,
} eFAST_TYPE;

typedef enum eFAST_ERROR {
	eFAST_ERR_NONE = 0,
	eFAST_ERR_CODEC = -1,
	eFAST_ERR_SIZE = -2,
	eFAST_ERR_VALUE = -3,
	eFAST_ERR_TAG_OP = -4,
	eFAST_ERR_TAG_TYPE = -5,
	eFAST_ERR_CALL_SEQ = -6,
	eFAST_ERR_IO = -7,
} eFAST_ERROR;

//////////////////////////////////////////////////////////////////////


#define TAG_MAX_SLOT     0x7f // extendable to 0x7f
#define TAG_MAX_TID      0x3fff  // extendable to 0x3fff
#define TAG_MAX_OP       0x3F
#define TAG_MAX_REQ      0x1
#define TAG_MAX_TYPE     0xf

#define TAG_SHIFT_SLOT         0
#define TAG_SHIFT_TID          7
#define TAG_SHIFT_OP           21
#define TAG_SHIFT_REQ          27
#define TAG_SHIFT_TYPE         28


#define MAKE_TAG(type, req, op, tid, slot) \
	(u32 ((type) << TAG_SHIFT_TYPE) | u32 ((req) << TAG_SHIFT_REQ) | \
	u32((op)   << TAG_SHIFT_OP) | u32((tid)  << TAG_SHIFT_TID)  | \
	u32((slot) << TAG_SHIFT_SLOT))

#define MAX_PMAP_BYTES 16
#define MAX_PMAP_BITS  (7 * MAX_PMAP_BYTES)
#define MAX_MSG_SIZE  2048

typedef unsigned int fast_tag_t;

//////////////////////////////////////////////////////////////////////

enum eFAST_FIELDS {
	// 0-4
	eFAST_BASE_TID = 0,
	eFAST_MSG_TID = MAKE_TAG (eFAST_TYPE_U32, true, eFAST_OP_COPY, eFAST_BASE_TID, 0),
	eFAST_MSG_LEN = MAKE_TAG (eFAST_TYPE_U32, true, eFAST_OP_NONE, eFAST_BASE_TID, 0),
	eFAST_MSG_TYPE = MAKE_TAG (eFAST_TYPE_U32, true, eFAST_OP_COPY, eFAST_BASE_TID, 1),
};

//////////////////////////////////////////////////////////////////////
#define MAX_STR_LEN 50
class FastField 
{
public:
	FastField();
	~FastField();
	void Init(); 
	FastField(i32 exponent, i64 mantissa);
	FastField(i32 _i32);
	FastField(u32 _u32);
	FastField(i64 _i64);
	FastField(u64 _u64);
	FastField(u8 *str);
	FastField(const char *str);
	operator i64 (); 
	operator i32 (); 
	operator u64 (); 
	operator u32 (); 
	operator u8* (); 
	operator const char * (); 
	operator void * (); 
	operator double (); 

	union{
		struct {
			i32 m_i32;
			i64 m_i64;
		};
		struct {
			u32 m_u32;
		};
		struct {
			u64 m_u64;
		};
		struct {
			u8 m_str[MAX_STR_LEN];
		};
	};
	bool valid;
	u8 none;
};
//
//////////////////////////////////////////////////////////////////////
typedef struct FASTPMap {
	u8 bits[MAX_PMAP_BITS];
	u32 size;
	u32 max_pos;
} FASTPMap;

typedef struct FASTBuffer {
	int fd;

	u8* head;
	u8* tail;
	u8* end;

	u8 data[MAX_MSG_SIZE];
} FASTBuffer;

typedef struct FASTGroup {
	FASTPMap pmap;
	u8 data[MAX_MSG_SIZE];
	u32 iSize;
} FASTGroup;

typedef struct FASTCodecError {
	char fn[1024];
	char text[1024];

	fast_tag_t tag;
	eFAST_ERROR code;
} FASTCodecError;

class FastFields {
public:
	FastFields() {
		memset( &values[0], 0, sizeof(FastField)*TAG_MAX_SLOT);
	}
	FastField values[TAG_MAX_SLOT];
};//////////////////////////////////////////////////////////////////////

#define FAST_CODEC_MAGIC 0xC0DEC

typedef struct FASTCodec {
	u32 magic;

	char name[1024];

	FASTPMap pmap;

	FASTBuffer msg;
	FASTBuffer input;
	FASTBuffer output;

	FastFields *cv[TAG_MAX_TID];

	// Config variables
	int count;
	//int skip_io;
	int verbose;

	// State variables
	int curr_tag;
	int in_message;

	FASTCodecError error[1];
} FASTCodec;


class FASTApi;

template<typename T>
int emitT(FASTApi *rthis, fast_tag_t tag, T data);

template<typename T>
int parseT(FASTApi *rthis, fast_tag_t tag, T *data, int sign_mask, bool isRequired);

template<typename T, typename Q>
int encodeT(FASTApi *rthis, fast_tag_t tag, T value);

template<typename T, typename Q, typename S>
int decodeT(FASTApi *rthis, fast_tag_t tag, T* value, eFAST_SIGN_MASK mask_type, 
			eFAST_SIGN_MASK mask_type_second, eFAST_TYPE fast_type,
			eFAST_TYPE fast_type_second, T* dictValue, bool isRequired, int opValue = -1);
//////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
extern "C" {
#endif


	class FASTApi {
	public:

		FASTApi() {
			cl_count   = 0;
			cl_decode  = 0;
			bitMask[0] = 64;
			bitMask[1] = 32;
			bitMask[2] = 16;
			bitMask[3] = 8;
			bitMask[4] = 4;
			bitMask[5] = 2;
			bitMask[6] = 1;
			bitMask[7] = 0;
			m_buffer[0] = 0;


			init_platform_io();
			create_codec();
		}
		~FASTApi() {
			destroy_codec();
		}

		/**
		* @defgroup fastapi fastapi functions
		* @{
		*/

		/**
		*	@brief Create and initialize the codec
		*
		*	@return	A pointer to opaque type FASTCodec
		*   @remark This function will allocate a segment of memory on your behalf to manage the
		*          codec state information.  The pointer returned should be treated as an opaque
		*          handle, it is a required parameter to most other fastapi functions.
		*/
		void create_codec(void);

		/**
		*	@brief Destroy the codec and release associated memory
		*
		*  @param	codec Pointer to a FASTCodec
		*  @remark  This function will free the segment of memory on your behalf originally allocated by the
		*          create_codec() function. The codec is invalid upon return.
		*/
		int destroy_codec();

		/**
		*	@brief Reset the codec state for a specific tag
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are reseting
		*   @remark This function will reset the state of the codec for the specific tag.
		*/
		void fast_reset_state(fast_tag_t tag);

		/**
		*	@brief Set the input FILE stream for a codec
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	fptr FILE Pointer to a FILE stream
		*   @remark The default input stream in stdin
		*/
		int set_codec_input(FILE* fptr);
		int set_codec_input(u8* pbuffer, unsigned int size);
		/**
		*	@brief Set the output FILE stream for a codec
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	fptr FILE Pointer to a FILE stream
		*   @remark The default output stream in stdout
		*/
		int fast_set_codec_output(FILE* fptr);
		int get_codec_output(u8** pbuffer, unsigned int* psize);

		/**
		*	@brief Make a FAST tag
		*/
		fast_tag_t fast_make_tag(eFAST_OP, eFAST_TYPE, u32 tid, u32 slot);

		/**
		*	@brief Decode the first tag of a new message
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*  @remark This function must be called to decode the first tag of a new message.
		*          The FASTCodecag should be the template ID
		*/
		int decode_message(fast_tag_t tag);

		/**
		*	@brief Complete the decoding of a message
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*  @remark This function must be called after the last tag of a message has been decoded
		*/
		int decode_message_end(fast_tag_t tag);

		/**
		*	@brief Decode a 32-bit signed integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data Pointer to a i32 that will contain the result
		*/
		int decode_i32(fast_tag_t tag, i32* data);

		/**
		*	@brief Decode a 32-bit unsigned integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data Pointer to a u32 that will contain the result
		*/
		int decode_u32(fast_tag_t tag, u32* data);
		i32 decode_message_length(fast_tag_t tag, u32* data) 
		{
			bool isRequired = get_tag_required ( tag );
			i32 iret = parseT(this, tag, data, SIGN_MASK_U32, isRequired);
			return iret;
		}
		int decode_group_count(fast_tag_t tag, u32* value);

		int decode_double(fast_tag_t tag, double* value);

		/**
		*	@brief Decode an ASCII String
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data Pointer to a char * that will contain the result
		*	@param	size The maximum number of chars data can hold
		*  @remark The resulting sting will NOT be NULL terminated, this function will only
		*          fill the string with char's decoded from the input.
		*/
		int decode_string(fast_tag_t tag, u8* data, int size);

		/**
		*	@brief Encode the first tag of a new message
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*  @remark This function must be called to encode the first tag of a new message.
		*          The FASTCodecag should be the template ID
		*/
		int encode_message(fast_tag_t tag);

		/**
		*	@brief Complete the encoding of a message
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are encoding
		*  @remark This function must be called after the last tag of a message has been encoded
		*/
		int encode_message_end(fast_tag_t tag);

		/**
		*	@brief Encode a 32-bit signed integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data i32 integer containing the value to encode
		*/
		int encode_i32(fast_tag_t tag, i32 data);
		int encode_i64(fast_tag_t tag, i64 data);

		/**
		*	@brief Encode a 32-bit unsigned integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data u32 integer containing the value to encode
		*/
		int encode_u32(fast_tag_t tag, u32 data);
		int encode_u64(fast_tag_t tag, u64 data);
		i32 decode_message_length(fast_tag_t tag, u32 value, u8* pbuffer);

		int encode_group_count(fast_tag_t tag, u32 data);

		int encode_double(fast_tag_t tag, double value);

		/**
		*	@brief Encode an ASCII String
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data char * containing the value to encode
		*	@param	size The number of characters to encode
		*  @remark This function will encode exactly size number of char's, it will not
		*          not assume a NULL terminated string.
		*/
		int encode_string(fast_tag_t tag, u8* data, int size);

		/**
		*	@brief Encode a 64-bit signed integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data i64 integer containing the value to encode
		*/
		int decode_i64(fast_tag_t tag, i64* value);

		/**
		*	@brief Encode a 64-bit unsigned integer
		*
		*	@param	codec Pointer to a FASTCodec
		*	@param	tag The FASTCodecag we are decoding
		*	@param	data i64 integer containing the value to encode
		*/
		int decode_u64(fast_tag_t tag, u64* value);
		/**
		*	@brief Format and print the last reported codec error to a human readable string to a FILE stream
		*
		*   @param	codec Pointer to a FASTCodec
		*   @param	fptr  FILE stream
		*   @returns The error string
		*/

		int print_error(FILE* fptr);

		/**
		*	@brief Convert the last reported codec error to a human readable string
		*
		*   @param	codec Pointer to a FASTCodec
		*   @returns The error string
		*/
		const char* error_string();

		/**
		*	@brief Convert a u8 byte arrray of characters to a u32
		*
		*	@param	 data Pointer to a u8 containing ASCII number
		*	@param	 size Lenght of data
		*  @returns The converted u32 number
		*  @remark This function will convert an ASCII string of numbers to a binary value
		*          All characters must be in range of '0' - '9'
		*/
		u32 ascii_to_u32(u8* data, int size);

		void reset_buffer(FASTBuffer* buffer);

		void init_buffer(FASTBuffer* buffer, int fd);

		int empty_buffer_pointer(FASTBuffer* buffer);

		int get_buffer_left(FASTBuffer* buffer);

		int get_buffer_size(FASTBuffer* buffer);

		int get_buffer_used(FASTBuffer* buffer);

		u32 get_tag_operator(u32 tag);

		bool get_tag_required(u32 tag);

		u32 get_tag_slot(u32 tag);

		u32 get_tag_tid(u32 tag);

		u32 get_tag_type(u32 tag);

		FastField& get(u32 tag);

		u8* get_string(u32 tag);

		void set_valid(u32 tag);

		void set_invalid(u32 tag);

		void set_none(u32 tag, u8 exponent = 0);
		
		bool is_none(u32 tag, eFAST_TYPE fastType = eFAST_TYPE_NULL);

		int is_valid(u32 tag);

		int is_equal(u32 tag, i32 data);

		int is_equal(u32 tag, i64 data);

		int is_equal(u32 tag, u32 data);

		int is_equal(u32 tag, u64 data);

		int is_equal(u32 tag, u8* data, int size);

		void set(u32 tag, FastField data);

		int toSize(u32 data);

		int toSize(u64 data);

		int toSize(i32 data);

		int toSize(i64 data);

		const char* forma_error_code(eFAST_ERROR code);

		const char* format_tag_operator(eFAST_OP op);

		const char* format_tag_type(eFAST_TYPE type);

		int set_error(const char* fn, fast_tag_t tag, eFAST_ERROR code,
			const char* format, ...);

		int check_codec(const char* fn);

		int check_type(const char* fn, fast_tag_t tag, u32 type);

		int bad_operator_error(const char* fn, fast_tag_t tag);

		int value_error(const char* fn, fast_tag_t tag);

		int get_presence_on_wire(fast_tag_t tag, eFAST_OP op, bool isRequired );

		void reset_presence_map();

		void backup_presence_map(FASTPMap &pmap);

		void restore_presence_map(FASTPMap pmap);

		void backup_group(FASTGroup &group);

		void restore_group(FASTGroup &group);

		bool need_presence_map(fast_tag_t tag, int op = -1, int req = -1 );

		int set_presence_map(fast_tag_t tag, u8 bset);

		int set_presence_map_x(fast_tag_t tag, eFAST_TYPE data_type);

		int emit_presence_map(FASTPMap *pmap, u8* data);

		void emit_byte(u8 data);

		int check_message_available(const char* fn, fast_tag_t tag, int size);

		int emit_double(fast_tag_t tag, i32 iExponent, i64 iMantissa, bool forceModify = false);

		int
			emit_string(fast_tag_t tag, u8* data, int size, bool forceModify =
			false);

		int parse_bytes(u8* data, int size);

		int parse_presence_map();

		int parse_double(fast_tag_t tag, double* data);

		void get_double_exponent_mantissa(double data, i32 &iExponent, i64 &iMantissa);
		void get_double_exponent_mantissa(const std::string & value, i32 &iExponent, i64 &iMantissa );

		int parse_string(fast_tag_t tag, u8* data, int size);

		int flush_group();

		int flush_message();

		int find_char_delta_offset(u8* a, u8* b, int size);

		FASTCodec codec;
		int cl_count;
		int cl_decode;
		char m_buffer[1024];
		u32 bitMask[8];

		void verbose() {
			codec.verbose++;
		}

		void count(int c) {
			cl_count = c;
		}
		void decode(int d) {
			cl_decode = d;
		}
		bool isdecode() {
			return cl_decode == 1;
		}
	};

	class FastTag {
	public:
		FastTag(eFAST_TYPE type, u32 opt, eFAST_OP op, u32 tid, u32 slot, u32 num,
			std::string value, std::string ref, std::string name) :
		m_type(type), m_req(opt), m_op(op), m_tid(tid), m_slot(slot),
			m_num(num), m_value(value), m_ref(ref), m_name(name) {
				if ((op == eFAST_OP_INCR && type == eFAST_TYPE_DECMIAL) || (op
					== eFAST_OP_INCR && type == eFAST_TYPE_ASCII) || (op
					== eFAST_OP_INCR && type == eFAST_TYPE_UNICODE) || (op
					== eFAST_OP_INCR && type == eFAST_TYPE_BYTEVECTOR) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_I32) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_U32) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_I64) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_U32) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_DECMIAL) || (op
					== eFAST_OP_TAIL && type == eFAST_TYPE_I32)) {
						std::stringstream throwstring;
						throwstring << "Increment is not supported for for opeartor" << op
							<< ", type" << type << ", name" << name << "[" << num
							<< "]";
						throw throwstring.str();
				}
				m_pmap_req = true;
				m_init = m_value;
				m_tag = MAKE_TAG(m_type, m_req, m_op, m_tid, m_slot);
		}

		FastTag() {
			m_pmap_req = true;
		}

		u32 get_tid() {
			return m_tid;
		}

		u32 get_num() {
			return m_num;
		}

		std::string get_init() {
			return m_init;
		}

		bool get_pmap_req() {
			return m_pmap_req;
		}

		void set_pmap_req(bool yes) {
			m_pmap_req = yes;
		}

		std::string get_ref_tid() {
			return m_ref;
		}

		std::string get_name() {
			return m_name;
		}

		eFAST_OP get_op() {
			return m_op;
		}

		u32 get_req() {
			return m_req;
		}

		FastTag(const FastTag& copy) {
			m_type = copy.m_type;
			m_req = copy.m_req;
			m_op = copy.m_op;
			m_slot = copy.m_slot;
			m_tid = copy.m_tid;
			m_tag = copy.m_tag;
			m_num = copy.m_num;
			m_value = copy.m_value;
			m_ref = copy.m_ref;
			m_name = copy.m_name;
			m_pmap_req = copy.m_pmap_req;
			m_init = copy.m_init;
		}
		void reset(u32 tid, u32 slot) {
			m_tid = tid;
			m_slot = slot;
			m_tag = MAKE_TAG(m_type, m_req, m_op, m_tid, m_slot);
		}

		eFAST_TYPE m_type;
		u32 m_req;
		eFAST_OP m_op;
		u32 m_tid;
		u32 m_slot;
		u32 m_tag;
		u32 m_num;
		bool m_pmap_req;
		std::string m_value;
		std::string m_init;
		std::string m_ref;
		std::string m_name;
	};

	/** @} */
#ifdef __cplusplus
}

#endif

#endif // _FASTApi_h_
